package gui;

import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.FocusEvent;
import java.awt.event.FocusListener;
import java.util.ArrayList;

import javax.swing.*;


import skyproc.Mod;
import skyproc.ModListing;
import skyproc.SPGlobal;
import skyproc.SPImporter;


public class StarterGUI extends JComponent {

	private static final long  serialVersionUID = 6079941785947964841L;
	private static final Color background       = new Color(0x3591EE);
	
	private JFrame     mainFrame;
	private JPanel     checkBoxArea;
	private JPopupMenu popup;

	public StarterGUI() {		

		try {
			UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
		} 
		catch (Exception e1) {
			e1.printStackTrace();
		}

		// Create main window frame
		mainFrame = new JFrame();
	
		
		 /////////////////////////////////
		// Create "OK" button
		JButton okButton = new JButton("OK");
		okButton.setAlignmentX(Component.CENTER_ALIGNMENT);
		okButton.setPreferredSize( new Dimension(70, 30) );
		okButton.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e){				
				loadMods();
			}
		});
		//////////////////////////////////
		
		
		 /////////////////////////////////
		// Create area with all mods
		checkBoxArea = new JPanel();
		GridLayout gl = new GridLayout(1,1);
		gl.setVgap(0);
		checkBoxArea.setLayout(gl);
		checkBoxArea.setBackground(Color.WHITE);
		
		// Create context menu for checkBoxArea
		createPopupMenu();
		//////////////////////////////////

		
		 ////////////////////////////////////////////////////
		// Attempt to populate checkBoxArea
		try {

			boolean checked = false;
			ArrayList<ModListing> modList = SPImporter.getLoadOrderModList();
			((GridLayout) checkBoxArea.getLayout()).setRows(modList.size());

			for(ModListing mod : SPImporter.getLoadOrderModList()) {
				checked = false;
				for(ModListing activeMod : SPImporter.getActiveModList()) {

					if(mod.equals(activeMod)) {
						checked = true;

					}
				}

				checkBoxArea.add(createCheckBox(mod.print(), checked));

			}

		} catch(Exception e) {
			System.out.println(e);
		}
		/////////////////////////////////////////////////////

		
		 //////////////////////////////////////////////
		// Create scroll pane for checkBoxArea
		JScrollPane scroller = new JScrollPane(checkBoxArea);
		scroller.setPreferredSize(new Dimension(300, 600));
		scroller.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS);
		scroller.getVerticalScrollBar().setUnitIncrement(10);
		scroller.getVerticalScrollBar().setBlockIncrement(30); 	// Not entirely sure what blockIncrement is but it sounds
																// bigger than unit so I set it to 3x its value.
		///////////////////////////////////////////////

		
		 ///////////////////////////////////
		// Add components to mainFrame
		mainFrame.getContentPane().setLayout(new BoxLayout(mainFrame.getContentPane(), BoxLayout.Y_AXIS));
		mainFrame.add(scroller);
		mainFrame.add(okButton);
		////////////////////////////////////
		
		 ///////////////////////////////////
		// Set mainFrame properties
		mainFrame.setTitle("Master/Plugin Selection");
		mainFrame.setResizable(false);		
		mainFrame.pack();
		mainFrame.setLocationRelativeTo(null);
		mainFrame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
		mainFrame.setVisible(true);
		////////////////////////////////////
	}

	/**
	 * Loads the selected mods, disposes the starting frame and
	 * initializes the main GUI.
	 */
	private void loadMods() {

		ArrayList<ModListing> mods = new ArrayList<ModListing>();

		for(Component box : checkBoxArea.getComponents()) {
			if(((AbstractButton) box).isSelected()) {
				mods.add(new ModListing(((AbstractButton) box).getText()));
			}
		}
		
		mainFrame.dispose();
		
		SPImporter importer = new SPImporter();
		importer.importMods(mods);
		
		new GUI();
	}

	/**
	 * Creates the popup menu used by the checkboxes.
	 */
	private void createPopupMenu() {
		JMenuItem menuItem;

		this.popup = new JPopupMenu();
		menuItem = new JMenuItem("Select All");
		menuItem.addActionListener(new ActionListener(){
			public void actionPerformed(ActionEvent e){
				selectAll();				
			}
		});		
		this.popup.add(menuItem);

		menuItem = new JMenuItem("Select None");
		menuItem.addActionListener(new ActionListener(){
			public void actionPerformed(ActionEvent e){
				selectNone();
			}
		});		
		this.popup.add(menuItem);

		menuItem = new JMenuItem("Invert Selection");
		menuItem.addActionListener(new ActionListener(){
			public void actionPerformed(ActionEvent e){				
				invertSelection();
			}
		});		
		this.popup.add(menuItem);
	}

	private void selectAll() {
		for( Component box : checkBoxArea.getComponents() ) {
			if( !((AbstractButton) box).isSelected() ) {
				((AbstractButton) box).setSelected(true);
			}
		}
	}
	private void selectNone() {
		for( Component box : checkBoxArea.getComponents() ) {
			if( ((AbstractButton) box).isSelected() ) {
				((AbstractButton) box).setSelected(false);
			}
		}
	}
	private void invertSelection() {
		for( Component box : checkBoxArea.getComponents() ) {
			AbstractButton ab = (AbstractButton)box; // To make the next line cleaner.
			ab.setSelected( !ab.isSelected() );
		}
	}

	/**
	 * Creates the check boxes that represent the mods to be loaded
	 * 
	 * @param modName The name of the mod.
	 * @param checked Whether or not the mod is checked.
	 * @return The created checkBox.
	 */
	private JCheckBox createCheckBox(String modName, boolean checked) {

		JCheckBox check = new JCheckBox(modName, checked);
		check.setBackground(Color.WHITE);
		check.setComponentPopupMenu(this.popup);
		check.setPreferredSize( new Dimension(255, 17) );
		check.addFocusListener( new FocusListener() {
			@Override
			public void focusGained(FocusEvent e) {
				((Component)e.getSource()).setBackground(StarterGUI.background);
			}
			@Override
			public void focusLost(FocusEvent e) {
				((Component)e.getSource()).setBackground(Color.WHITE);
			}
		});
		return check;
	}
}
